﻿namespace YidanSoft.Library.EditorUtility.WinControls
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Drawing;
    using System.Reflection;
    using System.Resources;
    using System.Runtime.CompilerServices;
    using System.Threading;
    using System.Windows.Forms;
    using YidanSoft.Library.EditorUtility.General;

    [ToolboxItem(false)]
    public class ColorPicker : UserControl
    {
        private const int ARROW_BUTTON_WIDTH = 15;
        internal ArrowButton arrowButton;
        private const int COLOR_PANEL_WIDTH = 20;
        internal ColorPickerDropDown colorDropDown;
        internal TextBox colorTextBox;
        private Container components = null;
        private System.Drawing.Color currentColor = System.Drawing.Color.White;
        private Rectangle displayColorRect;
        internal YidanSoft.Library.EditorUtility.General.DrawState drawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
        private ColorPickerEditCtrlHook editHook = null;
        private const int MARGIN = 8;
        private NewColorEventHandler NewColor;
        internal YidanSoft.Library.EditorUtility.General.DrawState previousState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
        private ResourceManager rm = null;
        private int TEXTBOX_HEIGHT = -1;

        public event NewColorEventHandler NewColor
        {
            add
            {
                NewColorEventHandler handler2;
                NewColorEventHandler newColor = this.NewColor;
                do
                {
                    handler2 = newColor;
                    NewColorEventHandler handler3 = (NewColorEventHandler) Delegate.Combine(handler2, value);
                    newColor = Interlocked.CompareExchange<NewColorEventHandler>(ref this.NewColor, handler3, handler2);
                }
                while (newColor != handler2);
            }
            remove
            {
                NewColorEventHandler handler2;
                NewColorEventHandler newColor = this.NewColor;
                do
                {
                    handler2 = newColor;
                    NewColorEventHandler handler3 = (NewColorEventHandler) Delegate.Remove(handler2, value);
                    newColor = Interlocked.CompareExchange<NewColorEventHandler>(ref this.NewColor, handler3, handler2);
                }
                while (newColor != handler2);
            }
        }

        public ColorPicker()
        {
            Assembly assembly = Assembly.GetAssembly(System.Type.GetType("YidanSoft.Library.EditorUtility.WinControls.ColorPicker"));
            this.rm = new ResourceManager("YidanSoft.Library.EditorUtility.Resources.ImagesColorPicker", assembly);
            this.InitializeComponent();
        }

        private void arrowButton_Click(object sender, EventArgs e)
        {
            Point point = new Point(0, 0);
            this.CalculateSafeDisplayPoint(ref point);
            this.colorDropDown.DesktopBounds = new Rectangle(point.X, point.Y, this.colorDropDown.ClientRectangle.Width, this.colorDropDown.ClientRectangle.Height);
            if (!this.colorDropDown.Visible)
            {
                this.colorDropDown.Show();
            }
            else
            {
                this.colorDropDown.Visible = false;
            }
        }

        private void CalculateSafeDisplayPoint(ref Point point)
        {
            Rectangle clientRectangle = base.ClientRectangle;
            clientRectangle = base.RectangleToScreen(clientRectangle);
            int width = Screen.PrimaryScreen.Bounds.Width;
            int height = Screen.PrimaryScreen.Bounds.Height;
            point.X = clientRectangle.Right - this.colorDropDown.Width;
            if (point.X < 0)
            {
                point.X = 0;
            }
            else if ((point.X + this.colorDropDown.Width) > width)
            {
                point.X = width - this.colorDropDown.Width;
            }
            point.Y = clientRectangle.Bottom + 1;
            if (point.Y < 0)
            {
                point.Y = 0;
            }
            else if ((point.Y + this.colorDropDown.Height) > height)
            {
                point.Y = (clientRectangle.Top - 1) - this.colorDropDown.Height;
            }
        }

        private void ColorChanged(object sender, ColorChangeArgs ea)
        {
            this.currentColor = ea.NewColor;
            this.InitializeColorTextBoxString(ea.NewColor, ea.SenderName);
        }

        private void ColorPanel_MouseEnter(object sender, EventArgs e)
        {
            this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Hot;
        }

        private void ColorPanel_MouseLeave(object sender, EventArgs e)
        {
            Point mousePosition = Control.MousePosition;
            if (!base.ClientRectangle.Contains(base.PointToClient(mousePosition)))
            {
                this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
                Debug.WriteLine("COLOR PANEL ON MOUSE LEAVE...");
            }
        }

        private void ColorPicker_Load(object sender, EventArgs e)
        {
            this.SetupChildrenControls();
        }

        private void ColorTextBox_GotFocus(object sender, EventArgs e)
        {
            this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Hot;
        }

        private void colorTextBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                string text = this.colorTextBox.Text;
                if (text.IndexOf(',') != -1)
                {
                    this.FormatRGB(text);
                }
                else
                {
                    try
                    {
                        if ((text.IndexOf('x') != -1) || (text.IndexOf('X') != -1))
                        {
                            int num = Convert.ToInt32(text, 0x10);
                            int red = (0xff0000 & num) >> 0x10;
                            int green = (0xff00 & num) >> 8;
                            int blue = 0xff & num;
                            System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue);
                            this.InitializeColorTextBoxString(color, "CustomTab");
                            return;
                        }
                        int num5 = Convert.ToInt32(text);
                        if ((num5 >= 0) && (num5 <= 0xff))
                        {
                            string str2 = "0, 0," + num5.ToString();
                            this.FormatRGB(str2);
                            return;
                        }
                    }
                    catch (Exception)
                    {
                        this.ResetTextBox("Invalid Color Value");
                        return;
                    }
                    System.Drawing.Color color2 = System.Drawing.Color.FromName(text);
                    if ((((color2.A != 0) || (color2.R != 0)) || (color2.G != 0)) || (color2.B != 0))
                    {
                        this.InitializeColorTextBoxString(color2, "CustomTab");
                    }
                    else
                    {
                        this.ResetTextBox("Invalid Color Value");
                    }
                }
            }
        }

        private void ColorTextBox_LostFocus(object sender, EventArgs e)
        {
            if (!this.arrowButton.ContainsFocus)
            {
                this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
            }
        }

        private void ColorTextBox_MouseEnter(object sender, EventArgs e)
        {
            this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Hot;
        }

        private void ColorTextBox_MouseLeave(object sender, EventArgs e)
        {
            Point mousePosition = Control.MousePosition;
            if (!base.ClientRectangle.Contains(base.PointToClient(mousePosition)))
            {
                this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void DrawColorPickerState()
        {
            using (Graphics graphics = base.CreateGraphics())
            {
                Pen pen;
                Rectangle clientRectangle = base.ClientRectangle;
                if (this.drawState != YidanSoft.Library.EditorUtility.General.DrawState.Disable)
                {
                    using (Brush brush = new SolidBrush(this.currentColor))
                    {
                        graphics.FillRectangle(brush, this.displayColorRect);
                        graphics.DrawRectangle(Pens.Black, this.displayColorRect.Left, this.displayColorRect.Top, this.displayColorRect.Width - 1, this.displayColorRect.Height - 1);
                    }
                }
                if (this.drawState == YidanSoft.Library.EditorUtility.General.DrawState.Normal)
                {
                    this.arrowButton.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
                    using (pen = new Pen(System.Drawing.Color.White))
                    {
                        graphics.DrawRectangle(pen, clientRectangle.Left, clientRectangle.Top, clientRectangle.Width - 1, clientRectangle.Height - 1);
                    }
                }
                else if (this.drawState == YidanSoft.Library.EditorUtility.General.DrawState.Hot)
                {
                    if (!((this.previousState == YidanSoft.Library.EditorUtility.General.DrawState.Pressed) && this.colorDropDown.Visible))
                    {
                        this.arrowButton.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Hot;
                    }
                    graphics.DrawRectangle(new Pen(ColorUtil.VSNetBorderColor), clientRectangle.Left, clientRectangle.Top, clientRectangle.Width - 1, clientRectangle.Height - 1);
                }
                else if (this.drawState == YidanSoft.Library.EditorUtility.General.DrawState.Pressed)
                {
                    this.arrowButton.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Pressed;
                    graphics.DrawRectangle(new Pen(ColorUtil.VSNetBorderColor), clientRectangle.Left, clientRectangle.Top, clientRectangle.Width - 1, clientRectangle.Height - 1);
                }
                else if (this.drawState == YidanSoft.Library.EditorUtility.General.DrawState.Disable)
                {
                    this.arrowButton.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Disable;
                    graphics.DrawRectangle(SystemPens.ControlDark, this.displayColorRect.Left, this.displayColorRect.Top, this.displayColorRect.Width - 1, this.displayColorRect.Height - 1);
                    using (pen = new Pen(System.Drawing.Color.White))
                    {
                        graphics.DrawRectangle(pen, clientRectangle.Left, clientRectangle.Top, clientRectangle.Width - 1, clientRectangle.Height - 1);
                    }
                }
            }
            this.previousState = this.drawState;
        }

        private void FormatRGB(string text)
        {
            string[] strArray = text.Split(new char[] { ',' });
            if (strArray.Length != 3)
            {
                this.ResetTextBox("Invalid color value");
            }
            else
            {
                string str = strArray[0];
                string str2 = strArray[1];
                string str3 = strArray[2];
                try
                {
                    int red = Convert.ToInt32(str);
                    int green = Convert.ToInt32(str2);
                    int blue = Convert.ToInt32(str3);
                    if ((((red < 0) || (red > 0xff)) || ((green < 0) || (green > 0xff))) || ((blue < 0) || (blue > 0xff)))
                    {
                        this.ResetTextBox("Out of bounds RGB value");
                    }
                    else
                    {
                        System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue);
                        System.Drawing.Color empty = System.Drawing.Color.Empty;
                        bool flag = ColorUtil.IsKnownColor(color, ref empty, true);
                        if (!flag)
                        {
                            flag = ColorUtil.IsSystemColor(color, ref empty);
                        }
                        if (flag)
                        {
                            color = empty;
                        }
                        this.currentColor = color;
                        this.InitializeColorTextBoxString(color, "CustomTab");
                    }
                }
                catch (InvalidCastException)
                {
                    this.ResetTextBox("Invalid RGB value");
                }
            }
        }

        private void InitializeColorTextBoxString(System.Drawing.Color color, string sender)
        {
            bool useTransparent = false;
            System.Drawing.Color empty = System.Drawing.Color.Empty;
            bool flag2 = true;
            if ((sender == "CustomTab") || (sender == null))
            {
                flag2 = ColorUtil.IsKnownColor(color, ref empty, useTransparent);
            }
            else
            {
                empty = color;
            }
            if (flag2)
            {
                color = empty;
                this.colorTextBox.Text = color.Name;
            }
            else
            {
                string str = ",";
                string str2 = color.R.ToString() + str + color.G.ToString() + str + color.B.ToString();
                this.colorTextBox.Text = str2;
            }
            this.colorDropDown.CurrentColor = color;
            this.colorTextBox.SelectionLength = 0;
            this.colorTextBox.SelectionStart = this.colorTextBox.Text.Length + 1;
            if (sender != null)
            {
                NewColorArgs e = new NewColorArgs(color);
                this.OnNewColor(e);
            }
        }

        private void InitializeComponent()
        {
            this.colorTextBox = new TextBox();
            this.arrowButton = new ArrowButton(this);
            base.SuspendLayout();
            this.colorTextBox.BorderStyle = BorderStyle.None;
            this.colorTextBox.Location = new Point(0x26, 4);
            this.colorTextBox.Name = "colorTextBox";
            this.colorTextBox.Size = new Size(0x7a, 13);
            this.colorTextBox.TabIndex = 0;
            this.colorTextBox.Text = "textBox1";
            this.colorTextBox.KeyUp += new KeyEventHandler(this.colorTextBox_KeyUp);
            this.arrowButton.BackColor = SystemColors.Control;
            this.arrowButton.FlatStyle = FlatStyle.Flat;
            this.arrowButton.Location = new Point(0xa6, 4);
            this.arrowButton.Name = "arrowButton";
            this.arrowButton.Size = new Size(0x12, 10);
            this.arrowButton.TabIndex = 1;
            this.arrowButton.Click += new EventHandler(this.arrowButton_Click);
            this.BackColor = System.Drawing.Color.White;
            base.Controls.AddRange(new Control[] { this.arrowButton, this.colorTextBox });
            base.Name = "ColorPicker";
            base.Size = new Size(190, 0x18);
            base.Load += new EventHandler(this.ColorPicker_Load);
            base.ResumeLayout(false);
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            if (base.Enabled)
            {
                this.drawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
            }
            else
            {
                this.drawState = YidanSoft.Library.EditorUtility.General.DrawState.Disable;
            }
            base.OnEnabledChanged(e);
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Hot;
        }

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            this.editHook = new ColorPickerEditCtrlHook(this);
            this.editHook.AssignHandle(this.colorTextBox.Handle);
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            Point mousePosition = Control.MousePosition;
            if (!base.ClientRectangle.Contains(base.PointToClient(mousePosition)))
            {
                this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Hot;
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            Point mousePosition = Control.MousePosition;
            if (!(base.ClientRectangle.Contains(base.PointToClient(mousePosition)) || this.colorTextBox.ContainsFocus))
            {
                this.DrawState = YidanSoft.Library.EditorUtility.General.DrawState.Normal;
                Debug.WriteLine("ON MOUSE LEAVE NORMAL PAINTING...");
            }
        }

        private void OnNewColor(NewColorArgs e)
        {
            this.currentColor = e.NewColor;
            if (this.NewColor != null)
            {
                this.NewColor(this, e);
            }
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
            this.DrawColorPickerState();
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (this.TEXTBOX_HEIGHT == -1)
            {
                this.TEXTBOX_HEIGHT = this.colorTextBox.Height;
            }
            if (base.Height != (this.TEXTBOX_HEIGHT + 8))
            {
                base.Height = this.TEXTBOX_HEIGHT + 8;
            }
            else
            {
                Rectangle clientRectangle = base.ClientRectangle;
                int width = clientRectangle.Width;
                int height = clientRectangle.Height;
                this.displayColorRect = new Rectangle(clientRectangle.Left + 4, clientRectangle.Top + 4, 20, height - 8);
                this.colorTextBox.Left = this.displayColorRect.Right + 4;
                this.colorTextBox.Top = clientRectangle.Top + 4;
                this.colorTextBox.Width = ((clientRectangle.Width - 20) - 15) - 10;
                this.colorTextBox.Height = height - 8;
                this.arrowButton.Left = this.colorTextBox.Right + 2;
                this.arrowButton.Top = clientRectangle.Top;
                this.arrowButton.Width = 15;
                this.arrowButton.Height = height;
            }
        }

        private void ResetTextBox(string ErrorMessage)
        {
            MessageBox.Show(this, ErrorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            this.InitializeColorTextBoxString(this.Color, null);
        }

        private void SetupChildrenControls()
        {
            Bitmap bitmap = (Bitmap) this.rm.GetObject("Arrow");
            bitmap.MakeTransparent(System.Drawing.Color.White);
            this.arrowButton.Image = bitmap;
            this.currentColor = this.Color;
            this.colorDropDown = new ColorPickerDropDown();
            this.colorDropDown.ColorChanged += new ColorChangeEventHandler(this.ColorChanged);
            this.colorTextBox.LostFocus += new EventHandler(this.ColorTextBox_LostFocus);
            this.colorTextBox.GotFocus += new EventHandler(this.ColorTextBox_GotFocus);
            this.colorTextBox.MouseLeave += new EventHandler(this.ColorTextBox_MouseLeave);
            this.colorTextBox.MouseEnter += new EventHandler(this.ColorTextBox_MouseEnter);
            this.colorTextBox.Font = new Font(this.colorTextBox.Font, this.colorTextBox.Font.Style | FontStyle.Bold);
            this.InitializeColorTextBoxString(this.Color, null);
        }

        public System.Drawing.Color Color
        {
            get
            {
                return this.currentColor;
            }
            set
            {
                this.currentColor = value;
            }
        }

        internal YidanSoft.Library.EditorUtility.General.DrawState DrawState
        {
            get
            {
                return this.drawState;
            }
            set
            {
                if (this.drawState != value)
                {
                    this.drawState = value;
                    base.Invalidate();
                }
            }
        }

        public delegate void NewColorEventHandler(object sender, NewColorArgs e);
    }
}

